package main

import (
	"bufio"
	"compress/zlib"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func parseTime() {
	layout := "2006-01-02 15:04:05"
	layout2 := "20060102150405"
	str := "1998-10-01 08:10:10"
	loc, _ := time.LoadLocation("Asia/Shanghai")
	t, _ := time.ParseInLocation(layout, str, loc)
	fmt.Println(t)
	s2 := t.Format(layout2)
	fmt.Println(s2)
}

func classDay() {
	now := time.Now()
	sub := int(6 - now.Weekday())
	interval := sub // 下一个周六距离今天隔了几天
	fmt.Println(sub)
	if sub == 0 {
		fmt.Println(now.Format("2006-01-02"))
		interval = 7
	}
	firstSaturday := now.Add(24 * time.Duration(interval) * time.Hour)
	fmt.Println(firstSaturday.Format("2006-01-02"))
	for i := 0; i < 3; i++ {
		firstSaturday = firstSaturday.Add(24 * time.Duration(interval) * time.Hour)
		fmt.Println(firstSaturday.Format("2006-01-02"))
	}
}

func readFile(inPath string, writer *bufio.Writer, writer2 *zlib.Writer) {
	if fin, err := os.Open(inPath); err != nil {
		fmt.Println(err)
		return
	} else {
		defer fin.Close()
		reader := bufio.NewReader(fin)
		for {
			if line, err := reader.ReadString('\n'); err != nil {
				if err == io.EOF {
					if len(line) > 0 {
						writer.WriteString(line)
						writer.WriteString("\n")
						writer2.Write([]byte(line))
						writer2.Write([]byte("\n"))
					}
				} else {
					fmt.Println(err)
				}
				break
			} else {
				writer.WriteString(line)
				writer2.Write([]byte(line))
			}
		}
	}
	return
}
func mergeFile(dir string) {
	fout, err := os.OpenFile("big.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout.Close()
	writer := bufio.NewWriter(fout)

	fout2, err := os.OpenFile("big.zlib", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout2.Close()
	writer2 := zlib.NewWriter(fout2)

	if files, err := ioutil.ReadDir(dir); err != nil {
		fmt.Println(err)
		return
	} else {
		for _, file := range files {
			if file.IsDir() {
				continue
			}
			baseName := file.Name()
			if strings.HasSuffix(baseName, ".txt") {
				inPath := filepath.Join(dir, baseName)
				readFile(inPath, writer, writer2)
			}
		}
	}
	writer.Flush()
	writer2.Flush()
}

type BufferedFileWriter struct {
	buffer     [1024]byte
	endPos     int
	fileHander *os.File
}

func NewBufferedFileWriter(fd *os.File) *BufferedFileWriter {
	return &BufferedFileWriter{
		fileHander: fd,
	}
}

func (writer BufferedFileWriter) Flush() {
	if writer.endPos > 0 {
		writer.fileHander.Write(writer.buffer[0:writer.endPos])
		writer.endPos = 0
	}
}

func (writer *BufferedFileWriter) Write(content []byte) {
	if len(content) >= 1024 {
		writer.Flush()
		writer.fileHander.Write(content)
	} else {
		if writer.endPos+len(content) >= 1024 {
			writer.Flush()
			writer.Write(content)
		} else {
			copy(writer.buffer[writer.endPos:], content)
			writer.endPos += len(content)
		}
	}
}

func (writer *BufferedFileWriter) WriteString(content string) {
	writer.Write([]byte(content))
}

func testBufferFileWriter() {
	fout, err := os.OpenFile("test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer fout.Close()
	writer := NewBufferedFileWriter(fout)
	for i := 0; i < 5; i++ {
		writer.WriteString("0123456789\n")
	}
	writer.Flush()
}

func main() {
	//parseTime()
	//classDay()
	//mergeFile("homework/dir")
	testBufferFileWriter()

}
